#include <printk.h>
#include <irq.h>
#include <haluart.h>

/*********************************************************************************
* 
* kprintf - 内核打印函数 (默认使用 uart0)
* 
* DESCRIPTION
*/

void kprintf 
    (
    const char_t * fmt, 
    ...
    )
    {
    static char_t buf[512] = {0};
    cpuflg_t      cpuflg;
    va_list       ap;

    va_start (ap, fmt);
    irq_disable_savecpuflg (&cpuflg);

    vskprintf (buf, fmt, ap);
    hal_uart_write (0, buf, 0); /* 把 buf 缓冲区 中的数据写入串口 */

    irq_enable_restcpuflg (&cpuflg);
    va_end (ap);

    return;
    }

/*********************************************************************************
* 
* knumber - 
* 
* DESCRIPTION
*/

char_t * knumber
    (
    char_t * str,
    uint_t   n, 
    sint_t   base
    )
    {
    register char_t * p;
    char_t            strbuf[36];

    p = &strbuf[36];

    *(--p) = 0;  

    if (n == 0)
        {
        *(--p) = '0';
        }
    else
        {
        do
            {
            *(--p) = "0123456789abcdef"[n % base]; 
            } while ( n /= base);
        }

    while (*p != 0)
        {
        *str++ = *p++;
        }

    return str;
    }

/*********************************************************************************
* 
* kstrcopy - 
* 
* DESCRIPTION
*/

char_t * kstrcopy
    (
    char_t * buf,
    char_t * str_s
    )
    {
    while (*str_s)
        {
        *buf = *str_s;
        buf++;
        str_s++;
        }

    return buf;
    }

/*********************************************************************************
* 
* vskprintf - 
* 
* DESCRIPTION
*/

void vskprintf
    (
    char_t       * buf,
    const char_t * fmt,
    va_list        args
    )
    {
    char_t * p        = buf;
    va_list  next_arg = args;

    while (*fmt)
        {
        if (*fmt != '%')
            {
            *p++ = *fmt++;
            continue;
            }

        fmt++;

        /* 判断格式 */

        switch (*fmt)
            {
            case 'x':
                p = knumber (p, va_arg (next_arg, uint_t), 16);
                fmt++;
                break;

            case 'd':
                p = knumber (p, va_arg (next_arg, uint_t), 10);
                fmt++;
                break;

            case 's':
                p= kstrcopy (p, (char_t *) va_arg (next_arg, uint_t));
                   fmt++;
                   break;

            default:
                break;
            }
        }

    *p = 0;
    return;
    }
